package com.navinfo.tripanalysis.common.arithmetic;

import com.navinfo.tripanalysis.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.tripanalysis.common.util.ArithmeticUtils;
import com.navinfo.tripanalysis.common.arithmetic.common.CommonData;
import com.navinfo.tripanalysis.common.arithmetic.common.OuterStatisticData;
import com.navinfo.tripanalysis.common.arithmetic.custom.VarDrivingNight;
import com.navinfo.tripanalysis.common.config.ConfigMap;
import com.navinfo.tripanalysis.common.protocol.java.EventDataPb;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Optional;

/**
 * 东风夜晚开车算法<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：统计、事件<br/>
 * @author web
 */
public class DrivingNight_DF extends AbstractArithmetic<VarDrivingNight> {
    /**
     * 事件类型
     */
    private static final EventDataPb.EventType eventType = EventDataPb.EventType.nightRunning;
    /**
     * 东风夜晚开车时间阈值  22点
     */
    private int startTime = ConfigMap.getInteger("DF_Night_Running_Time_Start");
    /**
     * 东风夜晚开车时间阈值  次日6点
     */
    private int endTime = ConfigMap.getInteger("DF_Night_Running_Time_end");


    /**
     * 判断当前是否为急减速
     */
    boolean isCurNightRunning() {
        CommonData commonData = getCommonData();
        int hour = LocalDateTime.ofInstant(Instant.ofEpochMilli(commonData.getGpsTime()), ZoneId.systemDefault()).getHour();
        return (hour>=startTime || (hour>=0 && hour<=endTime) ) && commonData.getSpeedKmh()>0 && commonData.getRotation()>0;
    }

    @Override
    public void calculate() {
        logger.debug("进入东风夜晚运行算法.[terminalId:{}]", terminalId);
        VarDrivingNight var = super.getObj();

        boolean preStatus = var.isPreNightRunning();
        boolean curStatus = isCurNightRunning();
        logger.debug("东风夜晚运行算法，夜晚运行状态：preStatus:{},curStatus:{}.[terminalId:{}]", preStatus, curStatus, terminalId);

        //算法计算
        switch (getEventStatus(preStatus, curStatus)) {
            case START:
                logger.debug("东风夜晚运行算法，事件开始.[terminalId:{}]", terminalId);
                startEventData(eventType);
                break;
            case IN:
                logger.debug("东风夜晚运行算法，事件中.[terminalId:{}]", terminalId);
                calcEventData(eventType);
                break;
            case END:
                logger.debug("东风夜晚运行算法，事件结束.[terminalId:{}]", terminalId);
                calcEventData(eventType);
                endEventData();
                break;
            default:
                logger.debug("东风夜晚运行算法，夜晚运行状态：上一次和本次都夜晚运行，跳出算法.[terminalId:{}]", terminalId);
        }


        //行程结束时要清理对应的未结束事件
        if (getCommonData().isTripLastNode()) {
            endEventData();
        }

        //设置上一个点状态、供下个点计算
        var.setPreNightRunning(curStatus);
        logger.debug("东风夜晚运行算法结束.[terminalId:{}]", terminalId);
    }

    private void endEventData() {
        endEventData(eventType, eventData -> {
            VarDrivingNight var = getObj();
            var.addNumber(1);
            var.addMileage( Optional.ofNullable(eventData.getExtendField05()).orElse(0.0));
            var.addFuel( Optional.ofNullable(eventData.getExtendField06()).orElse(0.0).intValue());
            var.addDuration(Optional.ofNullable(eventData.getDuration()).orElse(0L).intValue());
        });
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarDrivingNight var = getObj();
        statisticDataOut.setNightRunningMileage(ArithmeticUtils.mileageMToM(var.getMileage()));
        statisticDataOut.setNightRunningFuel(ArithmeticUtils.fuelMlToMl(var.getFuel()));
        statisticDataOut.setNightRunningDuration(ArithmeticUtils.timeMsToSecond(var.getDuration()));
        statisticDataOut.setNightRunningNumber(var.getNumber());
    }
}
